package org.jim.server.adapter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.jim.core.ImChannelContext;
import org.jim.core.exception.ImException;
import org.jim.core.packets.Message;
import org.jim.core.session.id.impl.UUIDSessionIdGenerator;
import org.jim.core.utils.JsonKit;
import org.jim.server.protocol.AbstractProtocolHandler;
import org.jim.server.util.ImServerKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 消息转换器工厂
 * 负责管理所有转换器并动态选择合适的转换器
 */
public class MessageConverterFactory {

    private static final Logger logger = LoggerFactory.getLogger(MessageConverterFactory.class);
    private static Map<Integer, MessageConverter> converters = new HashMap<Integer,MessageConverter>();

    static {
        // 添加转换器Demo
//        converters.put(DemoMessageConverter.COMMAND_DEMO.getNumber(),new DemoMessageConverter());
    }
    public static void addConverter(MessageConverter<? extends Message> converter) {
        converters.put(converter.getCmd().getNumber(),converter);
        logger.info("加载消息转换器: {}", converter.getClass().getSimpleName());
    }
    public static MessageConverter getConverter(int cmd) {
        return converters.get(cmd);
    }
    /**
     * 判断是否存在可用的消息转换器
     * @return 是否存在转换器
     */
    public static boolean hasConverters() {
        return !converters.isEmpty();
    }
    /**
     * 获取合适的转换器并转换消息
     * @param body 原始消息
     * @param channelContext 通道上下文
     * @return 转换后的消息
     */
    public static Message convert(byte[] body, ImChannelContext channelContext) throws ImException {
        if (body == null || body.length == 0 || !hasConverters()) {
            logger.warn("空消息体或没有适配器，不做转换");
            return null;
        }

        // 遍历所有转换器，找到支持当前消息格式的转换器
        for (MessageConverter<? extends Message> converter : converters.values()) {
            if (converter.supports(body)) {
                if (converter.getCmd() == null) {
                    throw new ImException("转换器[" + converter.getClass().getSimpleName() + "]未设置命令码");
                }
                try {
                    Message message = converter.convert(body, channelContext);
                    if (message != null) {
                        message.setCmd(converter.getCmd().getNumber());
                        // 保存原始消息
                        message.setSourceMessage(JSON.parseObject(new String(body, "UTF-8")));
                        return completeMessageFields(message);
                    }
                } catch (Exception e) {
                    logger.error("转换器[{}]处理消息失败", converter.getClass().getSimpleName(), e);
                }
            }
        }
        // 如果没有找到合适的转换器
        logger.warn("未找到合适的消息转换器");
        return null;
    }

    /**
     * 补全消息必要字段
     */
    private static Message completeMessageFields(Message message) {
        if (message == null) return null;

        // 自动生成消息ID（如果不存在）
        if (message.getId() == null || message.getId().isEmpty()) {
            message.setId(UUIDSessionIdGenerator.instance.sessionId(null));
        }

        // 自动设置创建时间（如果不存在）
        if (message.getCreateTime() == null) {
            message.setCreateTime(System.currentTimeMillis());
        }
        return message;
    }
}
